home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Viewers / aa_m68k_Intel_Only / ToyViewer1.2 / Source / hpcdtoppm.tproj / format.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-14  |  15.1 KB  |  663 lines

  1. /* hpcdtoppm (Hadmut's pcdtoppm) v0.6
  2. *  Copyright (c) 1992, 1993, 1994 by Hadmut Danisch (danisch@ira.uka.de).
  3. *  Permission to use and distribute this software and its
  4. *  documentation for noncommercial use and without fee is hereby granted,
  5. *  provided that the above copyright notice appear in all copies and that
  6. *  both that copyright notice and this permission notice appear in
  7. *  supporting documentation. It is not allowed to sell this software in 
  8. *  any way. This software is not public domain.
  9. */
  10.  
  11. #include "hpcdtoppm.h"
  12.  
  13. struct pcdquad { uBYTE len,highseq,lowseq,key;};
  14. struct pcdhqt  { uBYTE entries; struct pcdquad entry[256];};
  15. struct myhqt   { uINT seq,mask,len; uBYTE key; };
  16.  
  17. static struct myhqt myhuff0[256],myhuff1[256],myhuff2[256];
  18. static sINT          myhufflen0=0,myhufflen1=0,myhufflen2=0;
  19.  
  20.  
  21.  
  22.  
  23. static void readhqtsub(struct pcdhqt *quelle,struct myhqt *ziel,sINT *anzahl)
  24. #define E ((uINT) 1)
  25.  {sINT i;
  26.   struct pcdquad *sub;
  27.   struct myhqt *help;
  28.   *anzahl=(quelle->entries)+1;
  29.  
  30.   for(i=0;i<*anzahl;i++)
  31.    {sub = (struct pcdquad *)(((uBYTE *)quelle)+1+i*sizeof(*sub));
  32.     help=ziel+i;
  33.  
  34.     help->seq = (((uINT) sub->highseq) << 24) |(((uINT) sub->lowseq) << 16);
  35.     help->len = ((uINT) sub->len) +1;
  36.     help->key = sub->key;
  37.  
  38. #ifdef DEBUGhuff
  39.    fprintf(stderr," Anz: %d A1: %08x  A2: %08x X:%02x %02x %02x %02x Seq:  %08x   Laenge:  %d %d\n",
  40.           *anzahl,(uINT)sbuffer,(uINT)sub,
  41.           ((uBYTE *)sub)[0],((uBYTE *)sub)[1],((uBYTE *)sub)[2],((uBYTE *)sub)[3],
  42.           help->seq,help->len,sizeof(uBYTE));
  43. #endif
  44.  
  45.     if(help->len > 16) error(E_HUFF);
  46.  
  47.     help->mask = ~ ( (E << (32-help->len)) -1); 
  48.  
  49.   }
  50. #ifdef DEBUG
  51.   for(i=0;i<*anzahl;i++)
  52.    {help=ziel+i;
  53.     fprintf(stderr,"H: %3d  %08lx & %08lx (%2d) = %02x = %5d  %8x\n",
  54.         i, help->seq,help->mask,help->len,help->key,(sBYTE)help->key,
  55.         help->seq & (~help->mask));
  56.    }
  57. #endif
  58.  
  59. #undef E
  60. }
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68. void readhqt(sINT n)
  69.  {
  70.   uBYTE *ptr;
  71.  
  72.   melde("readhqt\n");
  73.   EREADBUF;
  74.   ptr = sbuffer;
  75.  
  76.   readhqtsub((struct pcdhqt *)ptr,myhuff0,&myhufflen0);
  77.  
  78.   if(n<2) return;
  79.   ptr+= 1 + 4* myhufflen0;
  80.   readhqtsub((struct pcdhqt *)ptr,myhuff1,&myhufflen1);
  81.  
  82.   if(n<3) return;
  83.   ptr+= 1 + 4* myhufflen1;
  84.   readhqtsub((struct pcdhqt *)ptr,myhuff2,&myhufflen2);
  85.  
  86. }
  87.  
  88. void readhqtx(sINT n)
  89.  {
  90.   uBYTE *ptr;
  91.  
  92.   melde("readhqtx\n");
  93.   ptr = sbuffer;
  94.  
  95.   readhqtsub((struct pcdhqt *)ptr,myhuff0,&myhufflen0);
  96.  
  97.   if(n<2) return;
  98.   ptr+= 1 + 4* myhufflen0;
  99.   readhqtsub((struct pcdhqt *)ptr,myhuff1,&myhufflen1);
  100.  
  101.   if(n<3) return;
  102.   ptr+= 1 + 4* myhufflen1;
  103.   readhqtsub((struct pcdhqt *)ptr,myhuff2,&myhufflen2);
  104.  
  105. }
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115. #ifdef FASTHUFF
  116.  
  117. static struct myhqt *HTAB0[0x10000],*HTAB1[0x10000],*HTAB2[0x10000];
  118.  
  119. static void inithuff(sINT hlen,struct myhqt *ptr,struct myhqt *TAB[])
  120.  {sINT i,n;
  121.   sINT seq,len;
  122.   struct myhqt *help;
  123.  
  124.   for(i=0;i<0x10000;i++) TAB[i]=0;
  125.  
  126.   for(n=0;n<hlen;n++)
  127.    {help=ptr+n;
  128.     seq=(help->seq)>>16;
  129.     len=help->len;
  130.  
  131.     for(i=0;i<(1<<(16-len));i++)
  132.       TAB[seq | i] = help;
  133.    }
  134.  }
  135. #endif
  136.  
  137.  
  138.  
  139. void decode(sizeinfo *si,int fak,implane *f,implane *f1,implane *f2,sINT autosync)
  140.  {dim w,h,hlen,hende,vlen,vende,anfang,ende;
  141.   sINT htlen,sum,do_inform,part;
  142.   uINT sreg,maxwidth;
  143.   uINT inh,n,zeile,segment,ident;
  144.   struct myhqt *hp;
  145.  
  146.   uBYTE *nptr;
  147.   uBYTE *lptr;
  148.  
  149. #define nextbuf  {  nptr=sbuffer; if(READBUF<1) error(E_READ); }
  150. #define checkbuf { if (nptr >= sbuffer + sizeof(sbuffer)) nextbuf; }
  151.  
  152. #ifdef U_TOO_LONG
  153. #define shiftreg(n) sreg = (sreg<< n ) & 0xffffffff;
  154. #else
  155. #define shiftreg(n) sreg<<=n;
  156. #endif
  157.  
  158. #define shiftout(n){ shiftreg(n); inh-=n; \
  159.                      while (inh<=24) \
  160.                       {checkbuf; \
  161.                        sreg |= ((uINT)(*(nptr++)))<<(24-inh);\
  162.                        inh+=8;\
  163.                       }\
  164.                     }  
  165. #define issync     ((sreg & 0xffffff00) == 0xfffffe00) 
  166. #define brutesync  ((sreg & 0x00fff000) == 0x00fff000) 
  167. #define seeksync { while (!brutesync) shiftout(8); while (!issync) shiftout(1);}
  168.  
  169. #ifdef FASTHUFF
  170.   struct myhqt **HTAB;
  171.   HTAB=0;
  172.   inithuff(myhufflen0,myhuff0,HTAB0);
  173.   inithuff(myhufflen1,myhuff1,HTAB1);
  174.   inithuff(myhufflen2,myhuff2,HTAB2);
  175. #define SETHUFF0 HTAB=HTAB0;
  176. #define SETHUFF1 HTAB=HTAB1;
  177. #define SETHUFF2 HTAB=HTAB2;
  178. #define FINDHUFF(x) {x=HTAB[sreg>>16];}
  179.  
  180. #else
  181.  
  182.   sINT i;
  183.   struct myhqt *htptr;
  184.   htptr=0;
  185. #define SETHUFF0 { htlen=myhufflen0 ; htptr = myhuff0 ; }
  186. #define SETHUFF1 { htlen=myhufflen1 ; htptr = myhuff1 ; }
  187. #define SETHUFF2 { htlen=myhufflen2 ; htptr = myhuff2 ; }
  188. #define FINDHUFF(x)  {for(i=0, x=htptr;(i<htlen) && ((sreg & x ->mask)!= x->seq); i++,x++); \
  189.                       if(i>=htlen) x=0;}
  190. #endif
  191.  
  192.   melde("decode\n");
  193.   anfang=ende=0;
  194.  
  195.   if(fak >= 0)
  196.    {w   =si->w     *fak;
  197.     h   =si->h     *fak;
  198.     hlen=si->rdhlen*fak;  hende=hlen;
  199.     vlen=si->rdvlen*fak;  vende=vlen;
  200.    }
  201.   else
  202.    {fak = -fak;
  203.     w   =si->w     /fak;
  204.     h   =si->h     /fak;
  205.     hlen=si->rdhlen/fak;  hende=hlen; 
  206.     vlen=si->rdvlen/fak;  vende=vlen;
  207.    }
  208.  
  209.     if ((hlen & 1) || (vlen & 1))
  210.     error(E_INTERN);  /* Must be all even */
  211.  
  212.   if( f  && ((! f->im) || ( f->iheight != vlen  ) ||  (f->iwidth != hlen  ))) error(E_INTERN);
  213.   if( f1 && ((!f1->im) || (f1->iheight != vlen/2) || (f1->iwidth != hlen/2))) error(E_INTERN);
  214.   if( f2 && ((!f2->im) || (f2->iheight != vlen/2) || (f2->iwidth != hlen/2))) error(E_INTERN);
  215.  
  216.   htlen=sreg=maxwidth=0;
  217.   zeile=0;
  218.   nextbuf;
  219.   inh=32;
  220.   lptr=0;
  221.   part=do_inform=0;
  222.   shiftout(16);
  223.   shiftout(16);
  224.  
  225.   if(autosync) seeksync;
  226.   
  227.   if(!issync) error(E_SEQ6);
  228.  
  229.   n=0;
  230.  
  231.   for(;;)
  232.    {
  233.     if (issync)
  234.      {shiftout(24);
  235.       ident=sreg>>16;
  236.       shiftout(16);
  237.  
  238.       zeile=(ident>>1) & 0x1fff;
  239.       segment=ident>>14;
  240.       if(do_inform) {fprintf(stderr,"Synchron mark found Line %d\n",zeile);do_inform=0;}
  241. #ifdef DEBUG
  242.       fprintf(stderr,"Id %4x Zeile: %6d Seg %3d Pix bisher: %5d  Position: %8lx+%5lx=%8x\n",
  243.           ident,zeile,segment,n,bufpos,nptr-sbuffer,bufpos+nptr-sbuffer);
  244. #endif
  245.  
  246.  
  247.       if(lptr && (n!=maxwidth)) error(E_SEQ1);
  248.       n=0;
  249.  
  250.       if(zeile==h) {RPRINT; return; }
  251.       if(zeile >h) error(E_SEQ2);    
  252.       switch(segment)
  253.        {
  254.         case 1: error(E_SEQ3);
  255.         case 0: maxwidth=w;
  256.                 if((!f) && autosync) {seeksync; n=maxwidth; break;}
  257.                 if(!f) error(E_SEQ7);
  258.                 if(zeile >= vende) {seeksync; n=maxwidth; break;}
  259.                 anfang=0; ende=hende;
  260.                 lptr=f->im + zeile * f->mwidth;
  261.                 SETHUFF0;
  262.                 part=0;
  263.                 break;
  264.  
  265.         case 2: maxwidth=w>>1;
  266.                 if(!f1) return;
  267.                 /*if((!f1) && autosync) {seeksync; break;}*/
  268.                 if(zeile >= vende) {seeksync; n=maxwidth; break;}
  269.                 anfang=0; ende=hende>>1;
  270.                 lptr=f1->im + (zeile >> 1)*f1->mwidth;
  271.                 SETHUFF1;
  272.                 part=1;
  273.                 break;
  274.  
  275.         case 3: maxwidth=w>>1;
  276.                 if(!f2) return;
  277.                 /*if((!f2) && autosync) {seeksync; break;}*/
  278.                 if(zeile >= vende) {seeksync; n=maxwidth; break;}
  279.                 anfang=0; ende=hende>>1;
  280.                 lptr=f2->im + (zeile >> 1)*f2->mwidth;
  281.                 SETHUFF2;
  282.                 part=2;
  283.                 break;
  284.  
  285.         default:error(E_SEQ3);
  286.     }
  287.      }
  288.     else
  289.      {
  290.       if(!lptr)      error(E_SEQ6);
  291.  
  292.       if(n>maxwidth) 
  293.         {
  294. #ifdef DEBUG
  295.          fprintf(stderr,"Register: %08lx Pos: %08lx\n",sreg,bufpos+nptr-sbuffer);
  296. #endif
  297.          error(E_SEQ4);
  298.        }
  299.       else
  300.        {FINDHUFF(hp);
  301.         if(!hp) error(E_SEQ5);
  302.         if((n>= anfang) && (n<ende))
  303.            {sum=((sINT)(*lptr)) + ((sBYTE)hp->key);
  304.             NORM(sum);
  305.             *(lptr++) = sum;
  306.            }
  307.  
  308.           n++; 
  309.           shiftout(hp->len);
  310.        }
  311.      }
  312.  
  313.    }
  314.  
  315.  
  316. #undef nextbuf  
  317. #undef checkbuf 
  318. #undef shiftout
  319. #undef issync
  320. #undef seeksync
  321.  
  322.  }
  323.  
  324.  
  325.  
  326. /* Decode the 64Base files */
  327. void decodex(FILE **fp, int tag , struct ic_descr *descr,sizeinfo *si,int fak,implane *f,sINT autosync)
  328.  {dim w,h,hlen,hende,vlen,vende,anfang,ende;
  329.   sINT htlen,sum,do_inform,part;
  330.   uINT sreg,maxwidth;
  331.   uINT inh,n,pos,zeile,segment,ident,sector,offset,length;
  332.   struct myhqt *hp;
  333.  
  334.   uBYTE *nptr;
  335.   uBYTE *lptr;
  336.  
  337.   int bufcont;
  338.  
  339.  
  340.  
  341. #define nextbuf  {  nptr=sbuffer; \
  342.                     do\
  343.                      {bufcont=fread(sbuffer,1,sizeof(sbuffer),*fp);\
  344.                       if(bufcont<1)\
  345.                        {if(feof(*fp)) fp++;\
  346.                         else error(E_READ);\
  347.                         if(!*fp)      return; }\
  348.                      } while (bufcont<1); }
  349.  
  350.  
  351. #define checkbuf { if (nptr >= sbuffer + bufcont) nextbuf; }
  352.  
  353. #ifdef U_TOO_LONG
  354. #define shiftreg(n) sreg = (sreg<< n ) & 0xffffffff;
  355. #else
  356. #define shiftreg(n) sreg<<=n;
  357. #endif
  358.  
  359. #define shiftout(n){ shiftreg(n); inh-=n; \
  360.                      while (inh<=24) \
  361.                       {checkbuf; \
  362.                        sreg |= ((uINT)(*(nptr++)))<<(24-inh);\
  363.                        inh+=8;\
  364.                       }\
  365.                     }  
  366. #define issync     ((sreg & 0xffffff00) == 0xfffffe00) 
  367. #define brutesync  ((sreg & 0x00fff000) == 0x00fff000) 
  368. #define seeksync { while ((!brutesync) && (bufcont>0)) shiftout(8); \
  369.                    while ((!issync) && (bufcont>0)) shiftout(1);}
  370.  
  371. #ifdef FASTHUFF
  372.   struct myhqt **HTAB;
  373.   HTAB=0;
  374.   switch(tag)
  375.    {case 0:  inithuff(myhufflen0,myhuff0,HTAB0); break;
  376.     case 1:  inithuff(myhufflen1,myhuff1,HTAB1); break;
  377.     case 2:  inithuff(myhufflen2,myhuff2,HTAB2); break;
  378.     default: error(E_INTERN);
  379.    }
  380. #define SETHUFF0 HTAB=HTAB0;
  381. #define SETHUFF1 HTAB=HTAB1;
  382. #define SETHUFF2 HTAB=HTAB2;
  383. #define FINDHUFF(x) {x=HTAB[sreg>>16];}
  384.  
  385. #else
  386.  
  387.   sINT i;
  388.   struct myhqt *htptr;
  389.   htptr=0;
  390. #define SETHUFF0 { htlen=myhufflen0 ; htptr = myhuff0 ; }
  391. #define SETHUFF1 { htlen=myhufflen1 ; htptr = myhuff1 ; }
  392. #define SETHUFF2 { htlen=myhufflen2 ; htptr = myhuff2 ; }
  393. #define FINDHUFF(x)  {for(i=0, x=htptr;(i<htlen) && ((sreg & x ->mask)!= x->seq); i++,x++); \
  394.                       if(i>=htlen) x=0;}
  395. #endif
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.   melde("decodex\n");
  404.   anfang=ende=0;
  405.   maxwidth=FILE32(descr->length);
  406.   h       =FILE16(descr->height);
  407.   offset  =FILE16(descr->offset);
  408.   length  =FILE32(descr->length);
  409.  
  410.  
  411.   if(fak >= 0)
  412.    {w   =si->w     *fak;
  413.     h   =si->h     *fak;
  414.     hlen=si->rdhlen*fak;  hende=hlen;
  415.     vlen=si->rdvlen*fak;  vende=vlen;
  416.    }
  417.   else
  418.    {fak = -fak;
  419.     w   =si->w     /fak;
  420.     h   =si->h     /fak;
  421.     hlen=si->rdhlen/fak;  hende=hlen; 
  422.     vlen=si->rdvlen/fak;  vende=vlen;
  423.    }
  424.  
  425.     if ((hlen & 1) || (vlen & 1))
  426.     error(E_INTERN);  /* Must be all even */
  427.  
  428.   if(!f) error(E_INTERN);
  429.  
  430. #ifdef DEBUG
  431.   fprintf(stderr,"fak %d\n",fak);
  432.   fprintf(stderr,"f->im %x  \n",(unsigned)f->im);
  433.   fprintf(stderr,"f->iheight  %d   %d\n",f->iheight,vlen);
  434.   fprintf(stderr,"f->iwidth   %d   %d\n",f->iwidth,hlen);
  435.   fprintf(stderr,"hoffset %d hende %d voffset %d vende %d\n",0,hende,0,vende);
  436. #endif
  437.  
  438.   if((! f->im) || ( f->iheight != vlen  ) ||  (f->iwidth != hlen  )) error(E_INTERN);
  439.  
  440.  
  441.   switch(tag)
  442.    {case 0: SETHUFF0; break;
  443.     case 1: SETHUFF1; break;
  444.     case 2: SETHUFF2; break;
  445.     default: error(E_INTERN);
  446.    }
  447.  
  448.  
  449.  
  450.   htlen=sreg=0;
  451.   zeile=0;
  452.   nextbuf;
  453.   inh=32;
  454.   lptr=0;
  455.   part=do_inform=0;
  456.   shiftout(16);
  457.   shiftout(16);
  458.  
  459.   if(autosync) seeksync;
  460.   
  461.   if(!issync) error(E_SEQ6);
  462.  
  463.   n=pos=0;
  464.  
  465.   for(;;)
  466.    {if (issync)
  467.      {shiftout(24);
  468.       ident=(sreg>>8) & 0xffffff;
  469.       shiftout(24);
  470.  
  471.       segment=(ident>>20) & 0xf;
  472.       zeile  =(ident>>6 ) & 0x3fff;
  473.       sector =(ident>>1 ) & 0x1f;
  474.  
  475.       if(segment != tag) {fprintf(stderr,"Falsches Segment\n"); return;}
  476.       if(do_inform)      {fprintf(stderr,"Synchron mark found Line %d\n",zeile);do_inform=0;}
  477.       if(zeile >= vende) return;
  478.    
  479.  
  480.  
  481. #ifdef DEBUG
  482.       fprintf(stderr,"Id %4x Zeile: %6d Seg %3d Sect %d Pix bisher: %5d \n",
  483.           ident,zeile,segment,sector,n);
  484. #endif
  485.  
  486.  
  487.       if(lptr && (n!=maxwidth)) error(E_SEQ1);
  488.  
  489.       n=0;
  490.  
  491.       if(zeile==h) {RPRINT; return; }
  492.       if(zeile >h) error(E_SEQ2);    
  493.       switch(tag)
  494.           {case 0: anfang=0; ende=hende;
  495.                    pos=offset + sector*length;
  496.                    if((pos>=ende) || (pos+length < anfang)) { n=maxwidth; seeksync; continue;}
  497.                    lptr=f->im + zeile * f->mwidth + (pos>anfang?(pos-anfang):0)  ;
  498.  
  499.                    break;
  500.            case 1:
  501.            case 2: anfang=0; ende=hende;
  502.                    pos=(offset>>1) + sector*length;
  503.                    if((pos>=ende) || (pos+length < anfang)) { n=maxwidth; seeksync; continue;}
  504.                    lptr=f->im + zeile * f->mwidth + (pos>anfang?(pos-anfang):0)  ;
  505.  
  506.                    break;
  507.  
  508.  
  509.            default: error(E_INTERN);
  510.           }
  511.      }
  512.     else /* for if (issync) */
  513.      {if(!lptr)      error(E_SEQ6);
  514.  
  515.       FINDHUFF(hp);
  516.       if(!hp) error(E_SEQ5);
  517.       if((pos >= anfang) && (pos<ende)) 
  518.            {sum=((sINT)(*lptr)) + ((sBYTE)hp->key);    
  519.             NORM(sum);   
  520.             *(lptr++) = sum;  
  521.            }
  522.       n++; pos++;
  523.       shiftout(hp->len);
  524.       if(n==maxwidth) 
  525.          { if ((zeile >= vende -1) && (pos >= hende)) return;
  526.            seeksync;
  527.          }
  528.      }
  529.    }
  530.  
  531.  
  532.  
  533.  
  534. #undef nextbuf  
  535. #undef checkbuf 
  536. #undef shiftout
  537. #undef issync
  538. #undef seeksync
  539.  
  540.  }
  541.  
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550.  
  551.  
  552.  
  553. enum ERRORS readplain(sizeinfo *si,int fak,implane *l,implane *c1,implane *c2)
  554.  {dim i,w,h,hlen,vlen;
  555.   uBYTE *pl=0,*pc1=0,*pc2=0;
  556.  
  557.   melde("readplain\n");
  558.  
  559. #ifdef DEBUG
  560.   fprintf(stderr,"readplain %d %d %d %d %d %d %d\n",fak,si->w,si->h,0,si->rdhlen,0,si->rdvlen);
  561. #endif
  562.  
  563.     if(fak >= 0) {
  564.     w   =si->w     *fak;
  565.     h   =si->h     *fak;
  566.     hlen=si->rdhlen*fak;
  567.     vlen=si->rdvlen*fak;
  568.     }else {
  569.     fak = -fak;
  570.     w   =si->w     /fak;
  571.     h   =si->h     /fak;
  572.     hlen=si->rdhlen/fak;
  573.     vlen=si->rdvlen/fak;
  574.     }
  575.  
  576.     if ((hlen & 1) || (vlen & 1))
  577.     error(E_INTERN);  /* Must be all even */
  578.  
  579.     
  580.   if(l)
  581.    { if ((l->mwidth<hlen) || (l->mheight<vlen) || (!l->im)) error(E_INTERN);
  582.      l->iwidth=hlen;
  583.      l->iheight=vlen;
  584.      pl=l->im;
  585.    }
  586.  
  587.   if(c1)
  588.    { if ((c1->mwidth<(hlen>>1)) || (c1->mheight<(vlen>>1)) || (!c1->im)) error(E_INTERN);
  589.      c1->iwidth=hlen>>1;
  590.      c1->iheight=vlen>>1;
  591.      pc1=c1->im;
  592.    }
  593.  
  594.   if(c2)
  595.    { if ((c2->mwidth<(hlen>>1)) || (c2->mheight<(vlen>>1)) || (!c2->im)) error(E_INTERN);
  596.      c2->iwidth=hlen>>1;
  597.      c2->iheight=vlen>>1;
  598.      pc2=c2->im;
  599.    }
  600.  
  601.   for(i=0;i<vlen>>1;i++)
  602.    {
  603.     if(pl)
  604.      { if(hlen==w)
  605.         {if(READ(pl,w)<1) return(E_READ);
  606.          pl+= l->mwidth;
  607.  
  608.          if(READ(pl,w)<1) return(E_READ);
  609.          pl+= l->mwidth;
  610.         }
  611.        else
  612.         {
  613.          if(READ(pl,hlen)<1) return(E_READ);
  614.          pl+= l->mwidth;
  615.          
  616.          SKIPr(w-hlen);
  617.  
  618.          if(READ(pl,hlen)<1) return(E_READ);
  619.          pl+= l->mwidth;
  620.  
  621.          SKIPr(w-hlen);         
  622.         }
  623.      }
  624.     else SKIPr(2*w);
  625.      
  626.     if(pc1)
  627.      {
  628.        if(hlen==w)
  629.         {
  630.          if(READ(pc1,w>>1)<1) return(E_READ);
  631.          pc1+= c1->mwidth;
  632.         }
  633.        else
  634.         {
  635.          if(READ(pc1,hlen>>1)<1) return(E_READ);
  636.          pc1+= c1->mwidth;
  637.          SKIPr((w-hlen)>>1);
  638.         }
  639.      }
  640.     else SKIPr(w>>1);
  641.      
  642.     if(pc2)
  643.      {
  644.        if(hlen==w)
  645.         {
  646.          if(READ(pc2,w>>1)<1) return(E_READ);
  647.          pc2+= c2->mwidth;
  648.         }
  649.        else
  650.         {
  651.          if(READ(pc2,hlen>>1)<1) return(E_READ);
  652.          pc2+= c2->mwidth;
  653.          SKIPr((w-hlen)>>1);
  654.         }
  655.      }
  656.     else SKIPr(w>>1);
  657.  
  658.  
  659.    }
  660.   RPRINT;
  661.   return E_NONE;
  662.  }
  663.